REM *** FFT09.04A - Q (=2^N) POINT FFT (POSITIVE FREQUENCIES ONLY) ***

10 SCREEN 9, 1: COLOR 15, 1: CLS 'SETUP DISPLAY SCREEN

12 PRINT "INPUT NUMBER OF DATA POINTS AS 2^N. "

14 INPUT "N = "; N

16 Q = 2 ^ N

20 Q2 = Q / 2: Q3 = Q2 - 1: Q4 = Q / 4: Q5 = Q4 - 1: Q8 = Q / 8

22 DIM C(2, Q), S(2, Q), KC(Q2), KS(Q2)'DIM DATA AND TWIDDLE FACTORS

30 PI = 3.141592653589793#: P2 = 2 * PI: K1 = P2 / Q

REM ***  GENERATE TWIDDLE FACTORS  ****

32 FOR I = 0 TO Q2: KC(I) = COS(K1 * I): KS(I) = SIN(K1 * I): NEXT

34 IOFLG = 1' SET OUTPUT TO NUMERIC DISPLAY

40 CLS ' DISPLAY MAIN MENU

50 PRINT SPC(30); "MAIN MENU": PRINT : PRINT

60 PRINT SPC(5); "1 = ANALYZE SINE FUNCTION": PRINT

62 PRINT SPC(5); "2 = INVERSE TRANSFORM": PRINT

64 PRINT SPC(5); "3 = SETUP DISPLAY": PRINT

66 PRINT SPC(5); "4 = EXIT": PRINT

70 PRINT SPC(10); "MAKE SELECTION :";

80 A$ = INKEY$: IF A$ = "" THEN 80

90 A = VAL(A$): ON A GOSUB 600, 200, 800, 990

95 GOTO 40

99  REM *****************

100 REM ***   PFFFT   ***

101 REM *****************

102 T9 = TIMER' GET STARTING TIME

104 REM                *** STAGE A ***

106 FOR I = 0 TO Q2 - 1: I2 = 2 * I

108 C(T0, I2) = (C(T1, I) + C(T1, Q2 + I)) / 2

110 C(T0, I2 + 1) = (C(T1, I) - C(T1, Q2 + I)) / 2

112 NEXT I

114 REM                *** STAGE B ***

116 FOR I = 0 TO Q2 - 1 STEP 2: I2 = 2 * I: IQ2 = I + Q2

118 C(T1, I2) = (C(T0, I) + C(T0, IQ2)) / 2

120 C(T1, I2 + 1) = (C(T0, I + 1)) / 2: S(T1, I2 + 1) = (C(T0, IQ2 + 1)) / 2

122 C(T1, I2 + 2) = (C(T0, I) - C(T0, IQ2)) / 2

124 NEXT I

130 REM                *** REMAINING STAGES ***

132 FOR M = 2 TO N - 1: QT = 2 ^ (M - 1)

134 QT2 = 2 * QT: KT1 = 2 ^ (N - M - 1)

136 FOR I = 0 TO Q3 STEP QT2: J1 = 2 * I: K = I + Q2

138 REM * COMPUTE DIRECT COMPONENTS *

140 FOR J = 0 TO QT: JA2 = J1 + J: JA = I + J: KT = J * KT1: KJ = K + J

142 C(T0, JA2) = .5 * (C(T1, JA) + C(T1, KJ) * KC(KT) - S(T1, KJ) * KS(KT))

144 S(T0, JA2) = .5 * (S(T1, JA) + C(T1, KJ) * KS(KT) + S(T1, KJ) * KC(KT))

146 NEXT J

150 REM * COMPUTE LATENT COMPONENTS *

152 FOR J = QT + 1 TO QT2: JA2 = J1 + J: JA = I + QT2 - J: KT = J * KT1: KJ = K + QT2 - J

154 C(T0, JA2) = .5 * (C(T1, JA) + C(T1, KJ) * KC(KT) + S(T1, KJ) * KS(KT))

156 S(T0, JA2) = .5 * (-S(T1, JA) + C(T1, KJ) * KS(KT) - S(T1, KJ) * KC(KT))

158 NEXT J

160 NEXT I

162 T0 = 1 - T0: T1 = 1 - T0

164 NEXT M

166 T9 = TIMER - T9

172 ON IOFLG GOSUB 300, 330

174 LOCATE 23, 20

176 PRINT : PRINT : INPUT "C/R TO CONTINUE:"; A$

178 RETURN



REM ****************************************************

REM *              INVERSE TRANSFORM                   *

REM ****************************************************

200 PRINT

202 FOR M = N - 1 TO 0 STEP -1' LOOP FOR STAGES OF COMPUTATION

204 QT2 = 2 ^ (M): QT = INT(QT2 / 2): QT4 = 2 * QT2: KT1 = 2 ^ (N - M - 1)

206 FOR I = 0 TO Q - (QT2) STEP QT4

208 FOR J = 0 TO QT: KI = J + (I / 2): KT = J * KT1: KJ = Q2 + KI

212 MCT = C(T1, J + I) - C(T1, I + QT2 - J): MST = S(T1, J + I) + S(T1, I + QT2 - J)

214 C(T0, KJ) = MCT * KC(KT) + MST * KS(KT)

216 S(T0, KJ) = MST * KC(KT) - MCT * KS(KT)

218 C(T0, KI) = (2 * C(T1, J + I)) - C(T0, KJ) * KC(KT) + S(T0, KJ) * KS(KT)

220 S(T0, KI) = (2 * S(T1, J + I)) - C(T0, KJ) * KS(KT) - S(T0, KJ) * KC(KT)

222 NEXT J

224 NEXT I

226 T0 = 1 - T0: T1 = 1 - T0

228 NEXT M

230 ON IOFLG GOSUB 350, 370

232 INPUT "C/R TO CONTINUE"; A$

234 RETURN



REM *******************************************************

REM *               DATA OUTPUT ROUTINES                  *

REM *******************************************************

300 REM **** PRINT OUTPUT DATA ****

302 CLS : PRINT "FREQ     F(COS)       F(SIN)       "'PRINT HEADING

304 PRINT : PRINT

306 FOR Z = 0 TO Q4: KPRT = Z + Q4

308 GOSUB 320' PRINT DATA

310 LCTR = LCTR + 1: IF LCTR = 20 THEN LCTR = 0: INPUT A$

312 NEXT Z

314 PRINT : PRINT "TIME ="; T9

316 LCTR = 0

318 RETURN

320 PRINT USING "###_    "; Z; :

322 PRINT USING "+##.#####_    "; C(T1, Z); S(T1, Z);

324 PRINT USING "###_    "; KPRT; :

326 PRINT USING "+##.#####_    "; C(T1, KPRT); S(T1, KPRT)

328 RETURN



REM ******  PLOT DATA ******

330 CLS : X0 = 50: Y0 = 300: XSF = 500 / Q2: YSF = 300

332 LINE (X0 - 1, 50)-(X0 - 1, Y0)' DRAW Y AXIS

334 LINE (X0, Y0)-(X0 + 500, Y0)' DRAW X AXIS

336 LINE (X0, Y0)-(X0, Y0)' SET PEN TO ORIGIN

338 FOR I = 0 TO Q2

340 YP = SQR(C(T1, I) ^ 2 + S(T1, I) ^ 2)' FIND RSS OF DATA POINT

342 LINE (X0 + XSF * I, Y0 - YSF * YP)-(X0 + XSF * I, Y0 - YSF * YP)' DRAW POINT

344 NEXT I

346 RETURN



350 REM **** PRINT RECONSTRUCTED OUTPUT DATA ****

352 CLS : PRINT "TIME     DATA POINT     NOT USED   TIME    DATA POINT  NOT USED    "'PRINT HEADING

354 PRINT : PRINT

356 FOR Z = 0 TO Q3: KPRT = Z + Q2

358 GOSUB 320' PRINT DATA

360 LCTR = LCTR + 1: IF LCTR = 16 THEN LCTR = 0: INPUT A$

362 NEXT Z

364 PRINT : PRINT "TIME ="; T9

366 LCTR = 0

368 RETURN



REM *****   PLOT RECONSTRUCTED DATA   *********

370 CLS : X0 = 50: Y0 = 170: XSF = 500 / Q: YSF = 100

372 LINE (X0 - 1, 50)-(X0 - 1, (2 * (Y0 - 50)) + 50)' DRAW Y AXIS

374 LINE (X0, Y0)-(X0 + 500, Y0)' DRAW X AXIS

376 LINE (X0, Y0)-(X0, Y0)' SET PEN TO ORIGIN

378 FOR I = 0 TO Q

380 YP = C(T1, I)' FIND DATA POINT

382 LINE (X0 + XSF * I, Y0 - YSF * YP)-(X0 + XSF * I, Y0 - YSF * YP)' DRAW POINT

384 NEXT I

386 RETURN



400 REM GENERATE SINEWAVE FUNCTION

410 FOR I = 0 TO Q

416 C(T1, I) = COS(F9 * K1 * I): S(T1, I) = 0

422 C(T0, I) = 0: S(T0, I) = 0

430 NEXT

440 RETURN



600 CLS : PRINT : PRINT : REM * GENERATE SINE WAVE COMPONENT *

602 INPUT "PLEASE SPECIFY FREQUENCY "; F9

604 PRINT "PREPARING DATA INPUT - PLEASE WAIT!"

606 T0 = 1: T1 = 0

610 GOSUB 400

616 GOSUB 350

618 INPUT A$

620 GOSUB 100

630 RETURN



800 REM ***  SETUP NUMERIC/GRAPHIC DISPLAY  ***

802 CLS : INPUT "GRAPHIC DISPLAY (Y/N)"; A$

804 IF A$ = "Y" THEN IOFLG = 2 ELSE IOFLG = 1

806 RETURN



990 END



